package mvc_generator.generator.car.jsf

import mvc_generator.mVCGenerator.ArithmeticExpression
import mvc_generator.mVCGenerator.ArithmeticPrimitive
import mvc_generator.mVCGenerator.ArithmeticVariable
import mvc_generator.mVCGenerator.BooleanExpression
import mvc_generator.mVCGenerator.BooleanPrimitive
import mvc_generator.mVCGenerator.BooleanVariable
import mvc_generator.mVCGenerator.DoubleExpression
import mvc_generator.mVCGenerator.Expression
import mvc_generator.mVCGenerator.IntegerExpression
import mvc_generator.mVCGenerator.ParenthesizedArithmeticExpression
import mvc_generator.mVCGenerator.ParenthesizedBooleanExpression
import mvc_generator.mVCGenerator.StringExpression
import mvc_generator.mVCGenerator.StringLengthExpression

class ExpressionGenerator {

	public def CharSequence generate(Expression expression) {
		var CharSequence result = ''''''

		if (expression instanceof BooleanExpression) {
			result = generate(expression as BooleanExpression);
		} else if (expression instanceof ArithmeticExpression) {
			result = generate(expression as ArithmeticExpression);
		} else {
			result = '''@Auto_Generated: «expression.getClass.name» is not a handled expression.'''
		}
	}

private def CharSequence generate(BooleanExpression booleanExpression) {
		var CharSequence result = ''''''

		if (booleanExpression.op1 instanceof BooleanVariable) {
			result = generate(booleanExpression.op1 as BooleanVariable);
		} else if (booleanExpression.op1 instanceof BooleanPrimitive) {
			result = generate(booleanExpression.op1 as BooleanPrimitive);
		} else {
			result = '''@AutoGenerated_Error: «booleanExpression.op1.getClass.name» is not a handled expression.''';
		}

		if (booleanExpression.symbol != null) {
			result = result + ''' «booleanExpression.symbol» '''

			if (booleanExpression.op2 instanceof BooleanVariable) {
				result = result + '''«generate(booleanExpression.op2 as BooleanVariable)»''';
			} else if (booleanExpression.op2 instanceof BooleanPrimitive) {
				result = result + '''«generate(booleanExpression.op2 as BooleanPrimitive)»''';
			} else if (booleanExpression.op2 instanceof ParenthesizedBooleanExpression) {
				result = result + '''«generate(booleanExpression.op2 as ParenthesizedBooleanExpression)»''';
			} else {
				result = '''@AutoGenerated_Error: «booleanExpression.op2.getClass.name» is not a handled expression.''';
			}
		}

		return result;
	}

	private def CharSequence generate(ArithmeticExpression arithmeticExpression) {
		var CharSequence result = ''''''

		if (arithmeticExpression.op1 instanceof ArithmeticVariable) {
			result = generate(arithmeticExpression.op1 as ArithmeticVariable);
		} else if (arithmeticExpression.op1 instanceof ArithmeticPrimitive) {
			result = generate(arithmeticExpression.op1 as ArithmeticPrimitive);
		} else if (arithmeticExpression.op1 instanceof StringLengthExpression) {
			result = generate(arithmeticExpression.op1 as StringLengthExpression);
		} else {
			result = '''@AutoGenerated_Error: «arithmeticExpression.op1.getClass.name» is not a handled expression.''';
		}

		if (arithmeticExpression.symbol != null) {
			result = result + ''' «arithmeticExpression.symbol» '''

			if (arithmeticExpression.op2 instanceof ArithmeticVariable) {
				result = result + '''«generate(arithmeticExpression.op2 as ArithmeticVariable)»''';
			} else if (arithmeticExpression.op2 instanceof ArithmeticPrimitive) {
				result = result + '''«generate(arithmeticExpression.op2 as ArithmeticPrimitive)»''';
			} else if (arithmeticExpression.op1 instanceof StringLengthExpression) {
				result = result +  '''«generate(arithmeticExpression.op1 as StringLengthExpression)»''' ;
			} else if (arithmeticExpression.op2 instanceof ParenthesizedArithmeticExpression) {
				result = result + '''«generate(arithmeticExpression.op2 as ParenthesizedArithmeticExpression)»''';
			} else {
				result = '''@AutoGenerated_Error: «arithmeticExpression.op2.getClass.name» is not a handled expression.''';
			}
		}

		return result;
	}

	private def CharSequence generate(ArithmeticVariable arithmeticVariable) {
		'''«arithmeticVariable.refer»'''
	}

	private def CharSequence generate(StringLengthExpression stringLengthExpression) {
		var result = '''''';

		if (stringLengthExpression.expression instanceof StringExpression) {
			result = '''"«(stringLengthExpression.expression as StringExpression).value»".length()'''
		} else if (stringLengthExpression.expression instanceof ArithmeticVariable) {
			result ='''«(stringLengthExpression.expression as ArithmeticVariable).refer».length()'''
		}

		return result;
	}

	private def CharSequence generate(ArithmeticPrimitive arithmeticPrimitive) {
		if (arithmeticPrimitive instanceof IntegerExpression) {
			'''«(arithmeticPrimitive as IntegerExpression).value»'''
		} else if (arithmeticPrimitive instanceof DoubleExpression) {
			'''«(arithmeticPrimitive as DoubleExpression).value».«(arithmeticPrimitive as DoubleExpression).decimalValue»'''
		} else if (arithmeticPrimitive instanceof StringExpression) {
			'''"«(arithmeticPrimitive as StringExpression).value»"'''
		} else {
			'''@AutoGenerated_Error: «arithmeticPrimitive.class.name» is not a handled ArithmeticPrimitive.'''
		}
	}

	private def CharSequence generate(ParenthesizedArithmeticExpression parenthesizedArithmeticExpression) {
		'''(«generate(parenthesizedArithmeticExpression.expression)»)'''
	}

	private def CharSequence generate(BooleanVariable booleanVariable) {
		'''«booleanVariable.refer»'''
	}

	private def CharSequence generate(BooleanPrimitive booleanPrimitive) {
		'''«booleanPrimitive.value»'''
	}

	private def CharSequence generate(ParenthesizedBooleanExpression parenthesizedBooleanExpression) {
		'''«generate(parenthesizedBooleanExpression.expression)»'''
	}
}
